package com.xy6.effectivejava.chapter04.item26;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.EmptyStackException;
import java.util.List;

/**
 * 泛型用法示例
 * 
 * @author zhang
 *
 * @param <E>
 */
public class MyStack<E> {

	private Object[] elements;
	private int size = 0;
	private static final int DEFAULT_INIT_CAPACITY = 16;

	public MyStack() {
		elements = new Object[DEFAULT_INIT_CAPACITY];
	}

	public void push(E e) {
		ensureCapacity();
		elements[size++] = e;
	}
	
	public E pop(){
		if(size == 0){
			throw new EmptyStackException();
		}
		@SuppressWarnings("unchecked")
		E result = (E) elements[--size];
		elements[size] = null; // eliminate obsolete reference 
		return result;
	}
	
	public boolean isEmpty(){
		return size == 0;
	}

	private void ensureCapacity() {
		if (elements.length == size) {
			elements = Arrays.copyOf(elements, 2 * size + 1);
		}
	}

	public void pushAll(Iterable<? extends E> src){
		for(E e : src){
			push(e);
		}
	}
	
	public static void main(String[] args){
		MyStack<Integer> stack = new MyStack<Integer>();
		stack.push(1);
		stack.push(2);
		stack.push(3);
		while(!stack.isEmpty()){
			System.out.println(stack.pop());
		}
		
		MyStack<Number> stack2 = new MyStack<Number>();
		List<Integer> elems = new ArrayList<>(2);
		elems.add(1);
		elems.add(2);
		Iterable<Integer> ints = elems;
		stack2.pushAll(ints);
		while(!stack2.isEmpty()){
			System.out.println(stack2.pop());
		}
	}
	
}
